#!/user/bin/env python
# coding:utf-8
"""
Author myYouTh
Date:2020/2/22 002213:42
Desc: 全局配置，作用于所有测试用例
"""

import copy
import pytest
from utils.readyaml import getyamlAllTestCase

# 缓存TestDatagetRegionCountry.yaml文件的测试用例
__GetRegionCoutry_testdata = {}


def is_in_fixturename(fixturename: str):
    """从metafunc.fixturename中过滤出对应的fixture"""
    if fixturename == "casename":
        return True
    elif fixturename == "caserequest":
        return True
    elif fixturename == "caseexpect":
        return True
    else:
        return False


@pytest.fixture(scope="function")
def caseforgetRegionCoutry():
    """getRegionCountry接口的测试用例，从TestDatagetRegionCountry.yaml文件中读取测试用例，包括请求数据和响应数据
    """
    global __GetRegionCoutry_testdata
    if not __GetRegionCoutry_testdata:
        raise NameError("测试用例的测试数据为空")
    return __GetRegionCoutry_testdata


def pytest_generate_tests(metafunc):
    """
    根据测试配置或定义测试函数的类或模块中指定的值生成测试用例, 在测试用例参数化收集前调用此钩子函数
    :param metafunc:共有五个属性值
                     metafunc.fixturenames:参数化收集时的参数名称
                     metafunc.module:使用参数名称进行参数化的测试用例所在的模块d对象
                     metafunc.config:测试用例会话
                     metafunc.function:测试用例对象,即函数或方法对象
                     metafunc.cls: 测试用例所属的类的类对象
    :return: none
    """
    #print(metafunc.fixturenames)
    # 测试用例中有casename、caserequest、caseexpect这三个fixture时，开始为测试用例设置参数化

    # 测试函数没有使用fixture时（fixture或者函数参数化时的形参），直接返回
    if not metafunc.fixturenames:
        return

    if all(list(filter(is_in_fixturename, metafunc.fixturenames))) and (list(filter(is_in_fixturename, metafunc.fixturenames))):
        # 所有测试函数的参数化的测试数据（测试用例名字、测试用例的测试数据、测试用例的预期结果）
        all_case_parametrize = []
        case_parametrize = []
        # 正在运行的测试函数的函数名或方法名
        current_function_name = metafunc.function.__qualname__
        # 从yaml中取出测试用例的测试数据
        testdata_dict = getyamlAllTestCase("TestDatagetRegionCountry.yaml")
        #print(testdata_dict.keys())
        # 从模块中提取不需要参数化的测试函数名字
        testcase = metafunc.module.__dict__
        del testcase[current_function_name]
        if not testcase:
            raise NameError("testcase字典为空")
        not_parametrize_testcase = [key for key in testcase.keys() if "request" in key]
        # 不需要参数化的测试函数所需的测试数据
        #__GetRegionCoutry_testdata = [dict((i, testdata_dict[i])) for i in not_parametrize_testcase if i in testdata_dict.keys()]
        if not not_parametrize_testcase:
            raise NameError("not_parametrize_testcase字典为空")
        #print(not_parametrize_testcase)
        for i in not_parametrize_testcase:
            if i in testdata_dict.keys():
                # 不需要参数化的测试数据
                #print(i)
                __GetRegionCoutry_testdata[i] = testdata_dict[i]
                # 需要参数化的测试数据
                del testdata_dict[i]

        #print(__GetRegionCoutry_testdata.keys())
        #print("----------")
        #print(testdata_dict.keys())

        for key, value in testdata_dict.items():
            case_parametrize.clear()
            case_parametrize.append(key)
            case_parametrize.append(value["request"])
            case_parametrize.append(value["expect"])
            all_case_parametrize.append(tuple(case_parametrize))
        else:
            if not all_case_parametrize:
                raise NameError("all_casez_parametrize列表为空")
            # 在测试用例运行前，对测试函数进行参数化设置
            metafunc.parametrize("casename, caserequest, caseexpect", all_case_parametrize)